<template>
  <div>
    <el-dialog
      title="添加子账号"
      v-model="state.isShow"
      lock-scroll
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      draggable
      align-center
      width="600px"
      @closed="closed"
    >
      <ul>
        <li class="flex h-[40px] items-center border rounded-l-[6px]">
          <div class="w-[100px] h-full flex items-center pl-2 rounded-l-[6px] bg-[#e5f1f5]">
            用户名
          </div>
          <div class="flex-1 w-0 flex items-center px-[10px]">
            <el-input
              :disabled="type == 'edit'"
              :readonly="type == 'edit'"
              v-model="form.Name"
              placeholder="请输入6-15位字母数字组合用户名"
            ></el-input>
          </div>
        </li>
        <li class="flex h-[40px] items-center border rounded-l-[6px] mt-[10px]">
          <div class="w-[100px] h-full flex items-center pl-2 rounded-l-[6px] bg-[#e5f1f5]">
            密码
          </div>
          <div class="flex-1 w-0 flex items-center px-[10px]">
            <el-input
              type="password"
              v-model="form.Password"
              placeholder="请输入6-16位字母数字组合的密码"
              show-password
            ></el-input>
          </div>
        </li>
        <li class="flex h-[40px] items-center border rounded-l-[6px] mt-[10px]">
          <div class="w-[100px] h-full flex items-center pl-2 rounded-l-[6px] bg-[#e5f1f5]">
            备注
          </div>
          <div class="flex-1 w-0 flex items-center px-[10px]">
            <el-input v-model="form.Remark"></el-input>
          </div>
        </li>
        <li class="flex h-[40px] items-center border rounded-l-[6px] mt-[10px]">
          <div class="w-[100px] h-full flex items-center pl-2 rounded-l-[6px] bg-[#e5f1f5]">
            状态
          </div>
          <div class="switch-list">
            <el-switch
              size="large"
              inline-prompt
              active-text="正常"
              inactive-text="关闭"
              :active-value="1"
              :inactive-value="0"
              v-model="form.IsUsed"
            />
          </div>
        </li>
        <li class="flex justify-between border rounded-l-[6px] mt-[10px]">
          <div class="flex-[0_0_100px] pl-2 pt-4 rounded-l-[6px] bg-[#e5f1f5]">
            <div>编辑</div>
            <div class="mt-2">
              <el-switch
                size="large"
                inline-prompt
                active-text="开启"
                inactive-text="关闭"
                :model-value="state.editChecked"
                @change="changeEditChecked"
              />
            </div>
          </div>
          <div class="switch-list">
            <template v-for="item in editPerms">
              <el-switch
                size="large"
                inline-prompt
                :active-text="item.Name"
                :inactive-text="item.Name"
                v-model="item.Checked"
              />
            </template>
          </div>
        </li>
        <li class="flex justify-between border rounded-l-[6px] mt-[10px]">
          <div class="flex-[0_0_100px] pl-2 py-2 rounded-l-[6px] bg-[#e5f1f5]">
            <div>申请</div>
            <div class="mt-2">
              <el-switch
                size="large"
                inline-prompt
                active-text="开启"
                inactive-text="关闭"
                :model-value="state.applyChecked"
                @change="changeApplyChecked"
              />
            </div>
          </div>
          <div class="switch-list">
            <template v-for="item in applyPerms">
              <el-switch
                size="large"
                inline-prompt
                :active-text="item.Name"
                :inactive-text="item.Name"
                v-model="item.Checked"
              />
            </template>
          </div>
        </li>
        <li class="flex justify-between border rounded-l-[6px] mt-[10px]">
          <div class="flex-[0_0_100px] pl-2 pt-4 rounded-l-[6px] bg-[#e5f1f5]">
            <div>菜单</div>
            <div class="mt-2">
              <el-switch
                size="large"
                inline-prompt
                active-text="开启"
                inactive-text="关闭"
                :model-value="state.menuChecked"
                @change="changeMenuChecked"
              />
            </div>
          </div>
          <div class="switch-list">
            <template v-for="item in menuPerms">
              <el-switch
                size="large"
                inline-prompt
                :active-text="item.Name"
                :inactive-text="item.Name"
                v-model="item.Checked"
              />
            </template>
          </div>
        </li>
      </ul>
      <template #footer>
        <el-button @click="closed">取 消</el-button>
        <el-button
          :disabled="state.updating"
          :loading="state.updating"
          type="primary"
          @click="confirm"
          >确 定</el-button
        >
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { message } from "@/utils/message";
import { debounce } from "lodash-es";
import { reqUserSubAccountsAdd, reqUserSubAccountsEdit, reqUserSubAccountsPerms } from "@/api/user";

const props = withDefaults(
  defineProps<{
    row: SubAccountMo | null;
    type?: "add" | "edit";
  }>(),
  {
    row: null,
    type: "add"
  }
);
const emit = defineEmits(["update"]);
const state = reactive({
  isShow: false,
  updating: false,
  editChecked: false,
  applyChecked: false,
  menuChecked: false
});

const form = reactive({
  Name: "",
  Password: "",
  Remark: "",
  IsUsed: 1,
  Perms: <number[]>[]
});

const editPerms = ref<PermsMo[]>([]);
const applyPerms = ref<PermsMo[]>([]);
const menuPerms = ref<PermsMo[]>([]);

const closed = () => {
  form.Name = "";
  form.Password = "";
  form.Remark = "";
  form.IsUsed = 1;
  state.isShow = false;
};

const open = () => {
  state.isShow = true;
  if (props.type == "add") {
    changeEditChecked(true);
    changeApplyChecked(true);
    changeMenuChecked(true);
  }
  if (props.type == "edit" && props.row) {
    form.Name = props.row.Name;
    form.Password = "";
    form.Remark = props.row.Remark;
    form.IsUsed = props.row.IsUsed;
    editPerms.value.forEach(item => {
      if (props.row?.Perms.includes(item.Id)) {
        item.Checked = true;
      }
    });
    applyPerms.value.forEach(item => {
      if (props.row?.Perms.includes(item.Id)) {
        item.Checked = true;
      }
    });
    menuPerms.value.forEach(item => {
      if (props.row?.Perms.includes(item.Id)) {
        item.Checked = true;
      }
    });
  }
};

const getPermsData = async () => {
  try {
    const res = await reqUserSubAccountsPerms();
    menuPerms.value = res.data
      .filter(item => item.MType == 0)
      .map(item => ({ ...item, Checked: false }));
    applyPerms.value = res.data
      .filter(item => item.MType == 1)
      .map(item => ({ ...item, Checked: false }));
    const edits = res.data
      .filter(item => item.MType == 2)
      .map(item => ({ ...item, Checked: false }));
    edits.sort((a, b) => a.Sort - b.Sort);
    editPerms.value = edits;
  } catch (error) {}
};

const confirm = debounce(
  async () => {
    if (!form.Name) {
      return message.warning("请输入用户名");
    }
    if (!form.Password && props.type == "add") {
      return message.warning("请输入输入密码");
    }
    try {
      state.updating = true;
      const Perms = [
        ...editPerms.value.filter(item => item.Checked).map(item => item.Id),
        ...applyPerms.value.filter(item => item.Checked).map(item => item.Id),
        ...menuPerms.value.filter(item => item.Checked).map(item => item.Id)
      ];
      if (props.type == "add") {
        await reqUserSubAccountsAdd({
          Name: form.Name,
          Password: form.Password,
          Remark: form.Remark,
          IsUsed: form.IsUsed,
          Perms: Perms
        });
      } else {
        await reqUserSubAccountsEdit({
          Id: props.row?.Id,
          Name: form.Name,
          ...(form.Password ? { Password: form.Password } : {}),
          Remark: form.Remark,
          IsUsed: form.IsUsed,
          Perms: Perms
        });
      }
      state.updating = false;
      message.success(props.type == "add" ? "添加成功" : "修改成功");
      emit("update");
      closed();
    } catch (error) {
      state.updating = false;
      console.log(error);
    }
  },
  500,
  { leading: true, trailing: false }
);

const changeEditChecked = (flag: boolean = false) => {
  state.editChecked = flag ?? !state.editChecked;
  if (state.editChecked) {
    editPerms.value.forEach(item => {
      item.Checked = true;
    });
  } else {
    editPerms.value.forEach(item => {
      item.Checked = false;
    });
  }
};
const changeApplyChecked = (flag: boolean = false) => {
  state.applyChecked = flag ?? !state.applyChecked;
  if (state.applyChecked) {
    applyPerms.value.forEach(item => {
      item.Checked = true;
    });
  } else {
    applyPerms.value.forEach(item => {
      item.Checked = false;
    });
  }
};
const changeMenuChecked = (flag: boolean = false) => {
  state.menuChecked = flag ?? !state.menuChecked;
  if (state.menuChecked) {
    menuPerms.value.forEach(item => {
      item.Checked = true;
    });
  } else {
    menuPerms.value.forEach(item => {
      item.Checked = false;
    });
  }
};

watch(
  () => editPerms.value,
  val => {
    val.every(item => item.Checked) && (state.editChecked = true);
    val.some(item => !item.Checked) && (state.editChecked = false);
  },
  {
    deep: true
  }
);
watch(
  () => applyPerms.value,
  val => {
    val.every(item => item.Checked) && (state.applyChecked = true);
    val.some(item => !item.Checked) && (state.applyChecked = false);
  },
  {
    deep: true
  }
);
watch(
  () => menuPerms.value,
  val => {
    val.every(item => item.Checked) && (state.menuChecked = true);
    val.some(item => !item.Checked) && (state.menuChecked = false);
  },
  {
    deep: true
  }
);

defineExpose({
  open
});
getPermsData();
</script>
<style scoped>
.switch-list {
  @apply flex-1 w-0 grid grid-cols-3 px-[10px] py-[4px] gap-y-[4px] gap-x-[10px];
}
</style>

<style scoped lang="scss">
:deep(.el-dialog__body) {
  padding: 20px;
}
.switch-list {
  :deep() {
    .el-switch__core {
      width: 100%;
    }
  }
}
</style>
